package com.carlinfo.demo.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;

/**
 * 一次性增加10000条记录到朝代表中
 * @author wangshMac
 *
 */
public class BatchMain
{
	/**
	 * 增加一条记录
	 * 
	 * ~批量执行10w记录到数据库中
	 * ~耗时
	 */
	public void insertOne()
	{
		long st = System.currentTimeMillis() ; 
		
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql:///student?useSSL=false";
		String user = "root";
		String password = "123456";
		
		Connection conn = null ;
		PreparedStatement ps = null ;
		
		String sql = "";
		try
		{
			Class.forName(driver);
			conn = DriverManager.getConnection(url, user, password);
			
			sql = "insert into mydata (name) values (?);" ; 
			Random random = new Random() ; 
			for(int i = 0 ; i < 200000 ; i ++)
			{
				ps = conn.prepareStatement(sql);
				/* 为占位符赋值 */
				ps.setObject(1, "名字_" + i );
				/**
				 * random.nextInt(100) + 100:是100到200呢
				 * random.nextInt(100):生成100以内的随机数
				 * (0 --> 100) + 100 ===> 100 --> 200 
				 */
				int res = ps.executeUpdate();
				System.out.println(i + "==正在执行==" + res);
			}
		} catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		} catch (SQLException e)
		{
			e.printStackTrace();
		} catch (Exception e)
		{
			e.printStackTrace();
			try
			{
				/* 回滚----后悔了 */
				if(conn != null)
				{
					/* 回滚事务 */
					conn.rollback();
				}
			} catch (SQLException e1)
			{
				e1.printStackTrace();
			}
		}finally
		{
			try
			{
				if(ps != null)
				{
					ps.close();
					ps = null ;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			
			try
			{
				if(conn != null)
				{
					conn.close();
					conn = null ;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			
		}
		
		/* 距离1970-01-01 00:00:00过了多长时间
		 * 执行执行前是一个数,执行后是一个数
		 * 那两个相减不就是执行执行所消耗的时间吗?
		 *  */
		long ed = System.currentTimeMillis() ; 
		System.out.println("==耗时==" + (ed - st));
	}
	
	/**
	 * 增加一条记录
	 * 
	 * ~批量执行10w记录到数据库中
	 * ~耗时
	 * 
	 * 批处理的优势是:如果有海量数据要操作数据库,所以使用批处理
	 */
	public void insertBatch()
	{
		long st = System.currentTimeMillis() ; 
		
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql:///student?useSSL=false";
		String user = "root";
		String password = "123456";
		
		Connection conn = null ;
		PreparedStatement ps = null ;
		
		String sql = "";
		try
		{
			Class.forName(driver);
			conn = DriverManager.getConnection(url, user, password);
			
			sql = "insert into mydata (name) values (?);" ; 
			Random random = new Random() ; 
			ps = conn.prepareStatement(sql);
			for(int i = 1 ; i < 1000 ; i ++)
			{
				/* 为占位符赋值 */
				ps.setObject(1, "名字_" + i );
				/**
				 * random.nextInt(100) + 100:是100到200呢
				 * random.nextInt(100):生成100以内的随机数
				 * (0 --> 100) + 100 ===> 100 --> 200 
				 */
				/* 将当前的对象增加到一个容器里面
				 * 一块处理 */
				ps.addBatch();
				
				/* 每隔多少条,提交一次,而不是在程序结束的时候执行 */
				if(i % 100 == 0 )
				{
					/* 每隔1000条执行一次批处理*/ 
					ps.executeBatch() ; 
					System.out.println("==提交了一次==" + i );
				}
			}
			
			/* 将容器里面的sql语句一块处理
			 * 每一条sql语句执行完以后的结果都放到了一个数组里面
			 * 
			 * 最后一次都要执行一下批处理
			 * 如果总的sql语句的条数是1120条;第1000条的时候提交了一次,那120条的时候咋办????
			 *  */
			int [] res = ps.executeBatch() ;
			System.out.println("===" + res.length);
			for(int i = 0 ; i < res.length ; i ++)
			{
				System.out.println(i +"==结果==>" + res[i]);
			}
		} catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		} catch (SQLException e)
		{
			e.printStackTrace();
		} catch (Exception e)
		{
			e.printStackTrace();
			try
			{
				/* 回滚----后悔了 */
				if(conn != null)
				{
					/* 回滚事务 */
					conn.rollback();
				}
			} catch (SQLException e1)
			{
				e1.printStackTrace();
			}
		}finally
		{
			try
			{
				if(ps != null)
				{
					ps.close();
					ps = null ;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			
			try
			{
				if(conn != null)
				{
					conn.close();
					conn = null ;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			
		}
		
		/* 距离1970-01-01 00:00:00过了多长时间
		 * 执行执行前是一个数,执行后是一个数
		 * 那两个相减不就是执行执行所消耗的时间吗?
		 *  */
		long ed = System.currentTimeMillis() ; 
		System.out.println("==耗时==" + (ed - st));
	}
	
	public static void main(String[] args)
	{
		System.out.println("=====");
		
		BatchMain bm = new BatchMain() ; 
//		bm.insertOne();
		
		bm.insertBatch();
	}
}

